Imports System
Imports System.IO
Imports System.Collections.Generic
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms

Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Imports Gosubb


Namespace Controls
    _
    Friend Class GraphGrid
        ' Pointer to the d3d
        Private mD3d As Graph3D = Nothing

        ' Real scales
        Private mXscale As Single() = Nothing
        Private mYscale As Single() = Nothing
        Private mXinv As Integer = 1
        Private mYinv As Integer = 1

        ' Normalised Scales
        Private mXscaleNorm As Single() = Nothing
        Private mYscaleNorm As Single() = Nothing

        ' Real data
        Private mData As Single(,) = Nothing
        Private mColour As Color32(,) = Nothing
        Private mDrawText As Boolean = False

        ' Normalised and adjusted data
        Private mVectors As Vector3(,) = Nothing
        Private mGraphLines As CustomVertex.PositionColored() = Nothing
        Private mGraphMesh As CustomVertex.PositionColored() = Nothing

        Private mTextArray() As GraphText

        Private mMax As Single = 10
        Private mMin As Single = 0


        Friend Sub NormaliseScale(ByRef scale() As Single, ByRef oScale() As Single, ByVal inv As Integer)
            If Not (scale Is Nothing) Then
                Dim min, max, range As Single
                Dim processScale(scale.Length) As Single

                min = scale(0)
                max = scale(0)
                For x As Integer = 1 To scale.Length - 1
                    If scale(x) < min Then
                        min = scale(x)
                    End If
                    If scale(x) > max Then
                        max = scale(x)
                    End If
                Next x
                range = max - min
                For x As Integer = 0 To scale.Length - 1
                    If inv = -1 Then
                        processScale(x) = 1 - (scale(x) - min) / range - 0.5F
                    Else
                        processScale(x) = (scale(x) - min) / range - 0.5F
                    End If
                Next x
                oScale = processScale
            End If
        End Sub 'NormaliseScale


        Friend Sub MakeNormalise()
            If Not (mXscaleNorm Is Nothing) And Not (mYscaleNorm Is Nothing) And Not (mData Is Nothing) And Not (mColour Is Nothing) Then
                mVectors = New Vector3(mXscaleNorm.Length, mYscaleNorm.Length) {}

                If mXscaleNorm.Length > 0 And mYscaleNorm.Length > 0 And mData.Length > 0 Then
                    If mData.GetUpperBound(0) = mXscaleNorm.GetUpperBound(0) And mData.GetUpperBound(1) = mYscaleNorm.GetUpperBound(0) Then
                        Dim x As Integer
                        For x = 0 To mXscaleNorm.Length - 1
                            Dim y As Integer
                            For y = 0 To mYscaleNorm.Length - 1
                                mVectors(x, y) = New Vector3(mXscaleNorm(x), mYscaleNorm(y), (mData(x, y) - mMin) / (mMax - mMin))
                            Next y
                        Next x
                        MakeVerts()
                        MakeText()
                        If Not (mD3d Is Nothing) Then
                            mD3d.ReGenerate()
                        End If
                    End If
                End If
            End If
        End Sub 'MakeNormalise

        Private Sub MakeText()
            If Me.DrawText Then
                If Not (mYscaleNorm Is Nothing) And Not (mXscaleNorm Is Nothing) Then
                    If mYscaleNorm.Length > 0 And mXscaleNorm.Length > 0 Then
                        mTextArray = New GraphText(mXscaleNorm.Length + mYscaleNorm.Length) {}
                        Dim count As Integer = 0
                        Dim x As Integer
                        For x = 0 To mXscaleNorm.Length - 1
                            mTextArray(count) = New GraphText()
                            mTextArray(count).Text = mXscale(x).ToString()
                            mTextArray(count).Rotation = -90
                            mTextArray(count).ScaleX = True
                            mTextArray(count).Position = New Vector3(mXscaleNorm(x), -0.6F, 0) 'ToDo: ++ operator not supported within expressions
                            count += 1
                        Next x
                        Dim y As Integer
                        For y = 0 To mYscaleNorm.Length - 1
                            mTextArray(count) = New GraphText()
                            mTextArray(count).Text = mYscale(y).ToString()
                            mTextArray(count).Rotation = 0
                            mTextArray(count).ScaleX = False
                            mTextArray(count).Position = New Vector3(-0.6F, mYscaleNorm(y), 0) 'ToDo: ++ operator not supported within expressions
                            count += 1
                        Next y
                    End If
                End If
            End If
        End Sub 'MakeText


        Private Sub MakeVerts()
            Dim wX As Integer = mXscaleNorm.Length
            Dim wY As Integer = mYscaleNorm.Length

            If wX > 1 And wY > 1 Then
                Dim verts As Integer = wX * wY * 6
                Dim lines As Integer = (wX * (wY - 1) + wY * (wX - 1)) * 2
                Dim count As Integer = 0

                ' check to see if the scales match the vectors now make the verticies
                If wX - 1 = mVectors.GetUpperBound(0) And wY - 1 = mVectors.GetUpperBound(1) Then
                    mGraphLines = New CustomVertex.PositionColored(lines) {}
                    mGraphMesh = New CustomVertex.PositionColored(verts) {}
                    For x As Integer = 0 To (wX - 1) - 1
                        ' Dim y As Integer
                        For y As Integer = 0 To (wY - 1) - 1
                            mGraphMesh(count).Position = mVectors(x, y)
                            mGraphMesh(count).Color = mColour(x, y) 'ToDo: ++ operator not supported within expressions
                            count += 1
                            mGraphMesh(count).Position = mVectors(x + 1, y)
                            mGraphMesh(count).Color = mColour(x + 1, y) 'ToDo: ++ operator not supported within expressions
                            count += 1
                            mGraphMesh(count).Position = mVectors(x + 1, y + 1)
                            mGraphMesh(count).Color = mColour(x + 1, y + 1) 'ToDo: ++ operator not supported within expressions
                            count += 1
                            mGraphMesh(count).Position = mVectors(x, y)
                            mGraphMesh(count).Color = mColour(x, y) 'ToDo: ++ operator not supported within expressions
                            count += 1
                            mGraphMesh(count).Position = mVectors(x + 1, y + 1)
                            mGraphMesh(count).Color = mColour(x + 1, y + 1) 'ToDo: ++ operator not supported within expressions
                            count += 1
                            mGraphMesh(count).Position = mVectors(x, y + 1)
                            mGraphMesh(count).Color = mColour(x, y + 1) 'ToDo: ++ operator not supported within expressions
                            count += 1
                        Next y
                    Next x
                    count = 0
                    For x As Integer = 0 To wX - 1
                        For y As Integer = 0 To (wY - 1) - 1
                            mGraphLines(count).Position = mVectors(x, y)
                            mGraphLines(count).Color = New Color32(255, mColour(x, y).Brighten(-50)) 'ToDo: ++ operator not supported within expressions
                            count += 1
                            mGraphLines(count).Position = mVectors(x, y + 1)
                            mGraphLines(count).Color = New Color32(255, mColour(x, y).Brighten(-50)) 'ToDo: ++ operator not supported within expressions
                            count += 1
                        Next y
                    Next x
                    For y As Integer = 0 To wY - 1
                        Dim x As Integer
                        For x = 0 To (wX - 1) - 1
                            mGraphLines(count).Position = mVectors(x, y)
                            mGraphLines(count).Color = New Color32(255, mColour(x, y).Brighten(-50)) 'ToDo: ++ operator not supported within expressions
                            count += 1
                            mGraphLines(count).Position = mVectors(x + 1, y)
                            mGraphLines(count).Color = New Color32(255, mColour(x, y).Brighten(-50)) 'ToDo: ++ operator not supported within expressions
                            count += 1
                        Next x
                    Next y
                End If
            Else
                If wY = 1 Or wX = 1 Then
                    Dim verts As Integer = (wY + wX - 2) * 6
                    Dim lines As Integer = verts - 4
                    Dim count As Integer = 0
                    Dim lCount As Integer = 0
                    If wY > 0 And wX > 0 Then
                        mGraphLines = New CustomVertex.PositionColored(lines) {}
                        mGraphMesh = New CustomVertex.PositionColored(verts) {}
                        If wX = 1 Then
                            Dim x As Integer = 0
                            Dim y As Integer
                            For y = 0 To (wY - 1) - 1
                                mGraphMesh(count).Position = New Vector3(mVectors(x, y).X, mVectors(x, y).Y, Me.Min)
                                mGraphMesh(count).Color = mColour(x, y) 'ToDo: ++ operator not supported within expressions
                                count += 1
                                mGraphLines(lCount) = mGraphMesh((count - 1)) 'ToDo: ++ operator not supported within expressions
                                lCount += 1
                                mGraphMesh(count).Position = mVectors(x, y)
                                mGraphMesh(count).Color = mColour(x, y) 'ToDo: ++ operator not supported within expressions
                                count += 1
                                mGraphLines(lCount) = mGraphMesh((count - 1)) 'ToDo: ++ operator not supported within expressions
                                lCount += 1
                                mGraphLines(lCount) = mGraphMesh((count - 1)) 'ToDo: ++ operator not supported within expressions
                                lCount += 1
                                mGraphMesh(count).Position = mVectors(x, y + 1)
                                mGraphMesh(count).Color = mColour(x, y + 1) 'ToDo: ++ operator not supported within expressions
                                count += 1
                                mGraphLines(lCount) = mGraphMesh((count - 1)) 'ToDo: ++ operator not supported within expressions
                                lCount += 1
                                mGraphMesh(count) = mGraphMesh((count - 3)) 'ToDo: ++ operator not supported within expressions
                                count += 1
                                mGraphMesh(count).Position = mVectors(x, y + 1)
                                mGraphMesh(count).Color = mColour(x, y + 1) 'ToDo: ++ operator not supported within expressions
                                count += 1
                                mGraphMesh(count).Position = New Vector3(mVectors(x, y + 1).X, mVectors(x, y + 1).Y, Me.Min)
                                mGraphMesh(count).Color = mColour(x, y + 1) 'ToDo: ++ operator not supported within expressions
                                count += 1
                            Next y
                            mGraphLines(lCount) = mGraphMesh((count - 2)) 'ToDo: ++ operator not supported within expressions
                            lCount += 1
                            mGraphLines(lCount) = mGraphMesh((count - 1)) 'ToDo: ++ operator not supported within expressions
                            lCount += 1
                        Else
                            Dim y As Integer = 0
                            Dim x As Integer
                            For x = 0 To (wX - 1) - 1
                                mGraphMesh(count).Position = New Vector3(mVectors(x, y).X, mVectors(x, y).Y, Me.Min)
                                mGraphMesh(count).Color = mColour(x, y) 'ToDo: ++ operator not supported within expressions
                                count += 1
                                mGraphLines(lCount) = mGraphMesh((count - 1)) 'ToDo: ++ operator not supported within expressions
                                lCount += 1
                                mGraphMesh(count).Position = mVectors(x, y)
                                mGraphMesh(count).Color = mColour(x, y) 'ToDo: ++ operator not supported within expressions
                                count += 1
                                mGraphLines(lCount) = mGraphMesh((count - 1)) 'ToDo: ++ operator not supported within expressions
                                lCount += 1
                                mGraphLines(lCount) = mGraphMesh((count - 1)) 'ToDo: ++ operator not supported within expressions
                                lCount += 1
                                mGraphMesh(count).Position = mVectors(x + 1, y)
                                mGraphMesh(count).Color = mColour(x + 1, y) 'ToDo: ++ operator not supported within expressions
                                count += 1
                                mGraphLines(lCount) = mGraphMesh((count - 1)) 'ToDo: ++ operator not supported within expressions
                                lCount += 1
                                mGraphMesh(count) = mGraphMesh((count - 3)) 'ToDo: ++ operator not supported within expressions
                                count += 1
                                mGraphMesh(count).Position = mVectors(x + 1, y)
                                mGraphMesh(count).Color = mColour(x + 1, y) 'ToDo: ++ operator not supported within expressions
                                count += 1
                                mGraphMesh(count).Position = New Vector3(mVectors(x + 1, y).X, mVectors(x + 1, y).Y, Me.Min)
                                mGraphMesh(count).Color = mColour(x + 1, y) 'ToDo: ++ operator not supported within expressions
                                count += 1
                            Next x
                            mGraphLines(lCount) = mGraphMesh((count - 2)) 'ToDo: ++ operator not supported within expressions
                            lCount += 1
                            mGraphLines(lCount) = mGraphMesh((count - 1)) 'ToDo: ++ operator not supported within expressions
                            lCount += 1
                        End If
                    End If
                End If
            End If
        End Sub 'MakeVerts 

        Public Property Max() As Single
            Get
                Return mMax
            End Get
            Set(ByVal value As Single)
                mMax = value
            End Set
        End Property

        Public Property Min() As Single
            Get
                Return mMin
            End Get
            Set(ByVal value As Single)
                mMin = value
            End Set
        End Property

        Public Property scaleX() As Single()
            Get
                Return mXscale
            End Get
            Set(ByVal value As Single())
                mXscale = value
                NormaliseScale(mXscale, mXscaleNorm, mXinv)
                MakeText()
            End Set
        End Property

        Public Property scaleY() As Single()
            Get
                Return mYscale
            End Get
            Set(ByVal value As Single())
                mYscale = value
                NormaliseScale(mYscale, mYscaleNorm, mYinv)
                MakeText()
            End Set
        End Property

        Friend WriteOnly Property Data() As Single(,)
            Set(ByVal value As Single(,))
                mData = value
            End Set
        End Property

        Friend WriteOnly Property Colour() As Color32(,)
            Set(ByVal value As Color32(,))
                mColour = value
            End Set
        End Property

        Public Property DrawText() As Boolean
            Get
                Return mDrawText
            End Get
            Set(ByVal value As Boolean)
                mDrawText = value
                MakeText()
            End Set
        End Property

        Friend ReadOnly Property TextArray() As GraphText()
            Get
                Return mTextArray
            End Get
        End Property
        ' Mesh/Lines Export properties

        Friend ReadOnly Property GraphLines() As CustomVertex.PositionColored()
            Get
                Return mGraphLines
            End Get
        End Property

        Friend ReadOnly Property GraphMesh() As CustomVertex.PositionColored()
            Get
                Return mGraphMesh
            End Get
        End Property

        Public Property scaleXinvert() As Integer
            Get
                Return mXinv
            End Get
            Set(ByVal value As Integer)
                mXinv = value
            End Set
        End Property

        Public Property scaleYinvert() As Integer
            Get
                Return mYinv
            End Get
            Set(ByVal value As Integer)
                mYinv = value
            End Set
        End Property

        ' set this every time when its put back into the graph3D class..

        Public Property D3d() As Graph3D
            Get
                Return mD3d
            End Get
            Set(ByVal value As Graph3D)
                mD3d = value
            End Set
        End Property
    End Class 'GraphGrid

    Friend Class GraphText
        Private mText As String = ""
        Private mPosition As Vector3
        Private mRotation As Single = 0
        Private mScaleX As Boolean = False


        Public Property ScaleX() As Boolean
            Get
                Return mScaleX
            End Get
            Set(ByVal value As Boolean)
                mScaleX = value
            End Set
        End Property

        Public Property [Text]() As String
            Get
                Return mText
            End Get
            Set(ByVal value As String)
                mText = value
            End Set
        End Property

        Public Property Position() As Vector3
            Get
                Return mPosition
            End Get
            Set(ByVal value As Vector3)
                mPosition = value
            End Set
        End Property

        Public Property Rotation() As Single
            Get
                Return mRotation
            End Get
            Set(ByVal value As Single)
                mRotation = value * (CSng(Math.PI) / 180)
            End Set
        End Property
    End Class 'GraphText 
End Namespace 'Gosubb
 _
Friend Class Graph3D
    Inherits Gosubb.Direct3D '
    'ToDo: Error processing original source shown below
    '
    '
    '------------^--- 'class', 'struct', 'interface' or 'delegate' expected
    '
    'ToDo: Error processing original source shown below
    '
    '
    '--------------------^--- Syntax error: ';' expected
    Private mTableDesc As String = ""
    Private mCubeMesh As AutoMesh
    Private mBackgroundColor As Color32 = Color.Black

    Private mGridPrimary As GraphGrid = Nothing
    Private mGridBase As GraphGrid = Nothing
    Private lookAngleUD As Single = CSng(Math.PI) / 8
    Private lookAngleLH As Single = CSng(Math.PI) / 2
    Private mMin As Single = 0
    Private mMax As Single = 10

    Private mDataVertex As AutoVertexBuffer
    Private mDataLines As AutoVertexBuffer
    Private mBaseVertex As AutoVertexBuffer
    Private mBaseLines As AutoVertexBuffer
    Private mTextMeshes() As AutoMesh
    Private mTextCenters() As Vector3


    Friend Sub New()
        MyBase.New()
        InitialiseGrid()
        'GenerateGrid(this, ref mDataVertex, ref mGridPrimary);
        InitializeComponent()
    End Sub 'New

    Private Sub InitializeComponent()
        AddHandler Me.DxRender3d, AddressOf Graph3D_DxRender3d
        AddHandler Me.DxLoaded, AddressOf Graph3D_DxLoaded
    End Sub 'InitializeComponent

    Private Sub InitialiseGrid()
        Dim Grid As New GraphGrid()
        Dim BBase As New GraphGrid()
        Grid.scaleX = New Single() {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8}
        Grid.scaleY = New Single() {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8}
        BBase.scaleX = Grid.scaleX
        BBase.scaleY = Grid.scaleY
        Dim tmp(16, 16) As Single
        Dim tmp3(16, 16) As Single
        Dim tmp2(16, 16) As Color32

        Dim x As Integer
        For x = 0 To 15
            Dim y As Integer
            For y = 0 To 15
                tmp(x, y) = (x + y) / 4
                tmp2(x, y) = New Color32(255 - x - y, x * 16, y * 16, 255 - x * 16)
                tmp3(x, y) = 0
            Next y
        Next x
        Grid.Colour = tmp2
        Grid.Data = tmp
        BBase.Data = tmp3
        BBase.Colour = tmp2
        BBase.DrawText = True
        BBase.Min = 10
        BBase.Max = 20
        Me.setBaseGrid(BBase)
        Me.setMainGrid(Grid)
    End Sub 'InitialiseGrid


    Public Property Max() As Single
        Get
            Return mMax
        End Get
        Set(ByVal value As Single)
            mMax = value
        End Set
    End Property

    Public Property Min() As Single
        Get
            Return mMin
        End Get
        Set(ByVal value As Single)
            mMin = value
        End Set
    End Property


    Friend Function getMainGrid() As GraphGrid
        Return mGridPrimary
    End Function 'getMainGrid

    Friend Sub setMainGrid(ByVal gIn As GraphGrid)
        mGridPrimary = gIn
        mGridPrimary.D3d = Me
        mGridPrimary.MakeNormalise()
    End Sub 'setMainGrid


    Friend Function getBaseGrid() As GraphGrid
        Return mGridBase
    End Function 'getBaseGrid

    Friend Sub setBaseGrid(ByVal gIn As GraphGrid)
        mGridBase = gIn
        mGridBase.D3d = Me
        mGridBase.MakeNormalise()
    End Sub 'setBaseGrid


    Public Property LookUpDown() As Single
        Get
            Return lookAngleUD * (180 / CSng(Math.PI))
        End Get
        Set(ByVal value As Single)
            If value < 0 Then
                lookAngleUD = 0.0F
            Else
                If value > 178 Then
                    lookAngleUD = 176 * CSng(Math.PI) / 180
                Else
                    lookAngleUD = value * CSng(Math.PI) / 180
                End If
            End If
        End Set
    End Property

    Public Property LookLeftRight() As Single
        Get
            Dim val As Single = lookAngleLH * CSng(CSng(180) / CSng(Math.PI))
            Return val
        End Get
        Set(ByVal value As Single)
            If value < 0 Then
                lookAngleLH = (value + 360) * (CSng(Math.PI) / 180)
            Else
                If value > 360 Then
                    lookAngleLH = (value - 360) * (CSng(Math.PI) / 180)
                Else
                    lookAngleLH = value * CSng(Math.PI) / 180
                End If
            End If
        End Set
    End Property


    Public Property BoundTable() As String
        Get
            Return mTableDesc
        End Get
        Set(ByVal value As String)
            mTableDesc = value
        End Set
    End Property

    Friend Sub GenerateAlphaMap(ByVal texture As Texture, ByVal minAlpha As Integer, ByVal maxAlpha As Integer, ByVal minColor As Integer, ByVal maxColor As Integer)
        ' Generate an alphamap
        Dim width As Integer = texture.GetLevelDescription(0).Width
        Dim height As Integer = texture.GetLevelDescription(0).Height
        Dim pitch As Integer
        Dim bm As Color32() = CType(texture.LockRectangle(GetType(Color32), 0, 0, pitch, width * height), Color32())

        ' Multiply by 3 because alpha calculation is R+G+B
        minColor *= 3
        maxColor *= 3

        Dim i As Integer
        For i = 0 To bm.Length - 1
            Dim color As Color32 = bm(i)

            Dim colorSum As Integer = color.iR + color.iG + color.iB ' alpha = color*3
            ' Calculate alpha
            Dim alpha As Integer
            If colorSum >= maxColor Then
                alpha = maxAlpha
            Else
                If colorSum <= minColor Then
                    alpha = minAlpha
                Else
                    ' Convert colorSum from (minColor..maxColor) to (minApha..maxAlpha)
                    alpha = (colorSum - minColor) * (maxAlpha - minAlpha) / (maxColor - minColor) + minAlpha
                End If
            End If
            bm(i) = New Color32(alpha, color)
        Next i
        texture.UnlockRectangle(0)
    End Sub 'GenerateAlphaMap


    Private Function CalcNormal(ByVal point1 As Vector3, ByVal point2 As Vector3, ByVal point3 As Vector3) As Vector3
        Dim retVector As Vector3 = Vector3.Cross(point2 - point1, point3 - point1)
        retVector = Vector3.Normalize(retVector)
        Return retVector
    End Function 'CalcNormal


    Friend Sub ReGenerate()
        If Not (Dx Is Nothing) Then
            Graph3D_DxLoaded(Me, Me.Dx)
        End If
    End Sub 'ReGenerate


    '/ <summary>
    '/ Occurs once after DirectX has been initialized for the first time.  
    '/ Setup AutoMesh's, AutoVertexBuffer's, and AutoTexture's here.
    '/ </summary>
    Private Sub Graph3D_DxLoaded(ByVal d3d As Gosubb.Direct3d, ByVal dx As Microsoft.DirectX.Direct3D.Device)
        If Not (dx Is Nothing) Then
            'InitialiseGrid();
            Dim Graph As GraphGrid = mGridPrimary
            Dim Base As GraphGrid = mGridBase
            Dim dump As Single

            If Not (Graph Is Nothing) Then
                If Not (Graph.GraphLines Is Nothing) Then
                    If Graph.GraphLines.Length > 0 Then
                        mDataLines = New AutoVertexBuffer(d3d, GetType(CustomVertex.PositionColored), Graph.GraphLines.Length, Usage.Dynamic, CustomVertex.PositionColored.Format, Pool.Default)
                        mDataLines.VB.SetData(Graph.GraphLines, 0, LockFlags.None)
                    End If
                End If
                If Not (Graph.GraphMesh Is Nothing) Then
                    If Graph.GraphMesh.Length > 0 Then
                        mDataVertex = New AutoVertexBuffer(d3d, GetType(CustomVertex.PositionColored), Graph.GraphMesh.Length, Usage.Dynamic, CustomVertex.PositionColored.Format, Pool.Default)
                        mDataVertex.VB.SetData(Graph.GraphMesh, 0, LockFlags.None)
                    End If
                End If
                If Graph.DrawText Then
                    If Graph.TextArray.Length > 0 Then
                        mTextMeshes = New AutoMesh(Graph.TextArray.Length) {}
                        mTextCenters = New Vector3(Graph.TextArray.Length) {}
                        Dim i As Integer
                        For i = 0 To mTextMeshes.Length - 1
                            mTextMeshes(i) = New AutoMesh(d3d, Mesh.TextFromFont(dx, New System.Drawing.Font("Arial", 8, FontStyle.Regular), Graph.TextArray(i).Text, 0.1F, 15.0F))
                            'mTextMeshes[i].BoundingBox(out mTextCenters[i], out outDont);
                            dump = mTextMeshes(i).BoundingSphereMin(mTextCenters(i))
                        Next i
                    End If
                End If
            End If
            If Not (Base Is Nothing) Then
                If Not (Base.GraphLines Is Nothing) Then
                    If Base.GraphLines.Length > 0 Then
                        mBaseLines = New AutoVertexBuffer(d3d, GetType(CustomVertex.PositionColored), Base.GraphLines.Length, Usage.Dynamic, CustomVertex.PositionColored.Format, Pool.Default)
                        mBaseLines.VB.SetData(Base.GraphLines, 0, LockFlags.None)
                    End If
                End If
                If Not (Base.GraphMesh Is Nothing) Then
                    If Base.GraphMesh.Length > 0 Then
                        mBaseVertex = New AutoVertexBuffer(d3d, GetType(CustomVertex.PositionColored), Base.GraphMesh.Length, Usage.Dynamic, CustomVertex.PositionColored.Format, Pool.Default)
                        mBaseVertex.VB.SetData(Base.GraphMesh, 0, LockFlags.None)
                    End If
                End If
                If Base.DrawText Then
                    If Base.TextArray.Length > 0 Then
                        mTextMeshes = New AutoMesh(Base.TextArray.Length) {}
                        mTextCenters = New Vector3(Base.TextArray.Length) {}
                        Dim i As Integer
                        For i = 0 To mTextMeshes.Length - 1
                            mTextMeshes(i) = New AutoMesh(d3d, Mesh.TextFromFont(dx, New System.Drawing.Font("Arial", 1, FontStyle.Regular), Base.TextArray(i).Text, 0.001F, 0.05F))
                            'mTextMeshes[i].BoundingBox(out mTextCenters[i], out outDont);
                            dump = mTextMeshes(i).BoundingSphereMin(mTextCenters(i))
                        Next i
                    End If
                End If
            End If
        End If
    End Sub 'Graph3D_DxLoaded


    ' More accurate than Environment.TickCount for smoother motion
    <System.Security.SuppressUnmanagedCodeSecurity(), DllImport("winmm.dll")> _
    Private Shared Function timeGetTime() As Integer

    End Function


    '/ <summary>
    '/ Occurs when it is time to render 3d objects.  Place all 3d
    '/ drawing code in this event.
    '/ </summary>
    Private Sub Graph3D_DxRender3d(ByVal d3d As Gosubb.Direct3d, ByVal dx As Microsoft.DirectX.Direct3D.Device)
        ' Setup the lights
        If Not (dx Is Nothing) Then
            dx.Lights(0).Enabled = True
            dx.Lights(0).Type = LightType.Directional
            dx.Lights(0).Direction = New Vector3(0, 0, -1)
            dx.Lights(0).Diffuse = Color.White
            dx.Lights(0).Position = New Vector3(0, 0, -400)


            'dx.Lights[0].Enabled = true;
            'dx.Lights[0].Ambient = Color.White;
            dx.RenderState.Lighting = False
            dx.RenderState.Ambient = Color.Red
            dx.RenderState.CullMode = Cull.None
            'dx.RenderState.AmbientColor = 40;
            ' lookAngleLH = pitch;
            'lookAngleUD = 12;
            Dim EyeFrom As New Vector3(0, -2, 200)
            EyeFrom.TransformCoordinate((Matrix.RotationYawPitchRoll(0, lookAngleUD, 0) * Matrix.RotationZ(lookAngleLH))) 'Matrix.RotationAxis(EyeFrom,lookAngleUD * (((float)Math.PI)/180))
            'Matrix.RotationAxis(new Vector3(0, 1, 0), lookAngleUD*(180/(float)Math.PI))
            '* Matrix.RotationAxis(new Vector3(0, 0, 1), lookAngleLH * (180 / (float)Math.PI)));
            '*Matrix.RotationAxis(new Vector3(0, 1.0F, 0), lookAngleUD)
            '*Matrix.RotationAxis(new Vector3(0, 0, 1.0F), lookAngleLH));
            ' Set viewer		
            dx.Transform.View = Matrix.LookAtLH(EyeFrom, New Vector3(0.0F, 0.0F, 0.5F), New Vector3(0.0F, 0.0F, 1.0F))
            '((mMax - mMin) / 2) + mMin)
            ' Set projection matrix
            dx.Transform.Projection = Matrix.OrthoLH(1.62F, 1.62F * (CSng(Bounds.Height) / CSng(Bounds.Width)), 0, 2000)
            'dx.Transform.Projection = Matrix.PerspectiveFovLH(
            '    (float)Math.PI / 4, 640f / 480f, 0, 2000.0f);
            dx.RenderState.NormalizeNormals = True

            ' int ticks = Environment.TickCount; // Safe, less accurate

            ' --------------------------------------------------------------
            ' Draw gosub logo texture
            ' --------------------------------------------------------------
            ' Setup to render texture
            'dx.SetTexture(0, mGosubTexture.T);
            ' dx.Material = GraphicsUtility.InitMaterial(Color.White);
            dx.RenderState.AlphaBlendEnable = True
            dx.RenderState.SourceBlend = Blend.SourceAlpha
            dx.RenderState.DestinationBlend = Blend.InvSourceAlpha
            dx.RenderState.ColorWriteEnable = ColorWriteEnable.RedGreenBlueAlpha
            dx.RenderState.AlphaBlendOperation = BlendOperation.Add
            dx.RenderState.ColorVertex = True
            dx.RenderState.TwoSidedStencilMode = True
            'dx.TextureState[0].AlphaOperation = TextureOperation.Modulate;
            dx.RenderState.PointSize = 2.0F

            ' Setup the world matrix to position (and scale and rotate) the model in 3d world space
            dx.Transform.World = Matrix.Translation(0, 0, 0) * Matrix.Scaling(1, 1, 1)
            ' Make it bigger
            If Not (mBaseVertex Is Nothing) Then
                dx.VertexFormat = mBaseVertex.VB.Description.VertexFormat
                dx.SetStreamSource(0, mBaseVertex.VB, 0)
                dx.DrawPrimitives(PrimitiveType.TriangleList, 0, mBaseVertex.NumVertices / 3)
            End If

            If Not (mBaseLines Is Nothing) Then
                dx.VertexFormat = mBaseLines.VB.Description.VertexFormat
                dx.SetStreamSource(0, mBaseLines.VB, 0)
                dx.DrawPrimitives(PrimitiveType.LineList, 0, mBaseLines.NumVertices / 2)
            End If

            'dx.VertexFormat = CustomVertex.PositionNormalColored.Format;
            If Not (mDataVertex Is Nothing) Then
                dx.VertexFormat = mDataVertex.VB.Description.VertexFormat
                dx.SetStreamSource(0, mDataVertex.VB, 0)
                dx.DrawPrimitives(PrimitiveType.TriangleList, 0, mDataVertex.NumVertices / 3)
            End If

            If Not (mDataLines Is Nothing) Then
                dx.VertexFormat = mDataLines.VB.Description.VertexFormat
                dx.SetStreamSource(0, mDataLines.VB, 0)
                dx.DrawPrimitives(PrimitiveType.LineList, 0, mDataLines.NumVertices / 2)
            End If
            dx.RenderState.Lighting = True
            If Not (mTextMeshes Is Nothing) And Not (mTextCenters Is Nothing) Then
                If mTextMeshes.Length > 0 Then
                    ' Determine which grid is the text grid
                    Dim ptGrid As GraphGrid = Nothing
                    If getMainGrid().DrawText Then
                        ptGrid = getMainGrid()
                    End If
                    If getBaseGrid().DrawText Then
                        ptGrid = getBaseGrid()
                    End If
                    If Not (ptGrid Is Nothing) Then
                        Dim [text] As GraphText() = ptGrid.TextArray
                        If Not ([text] Is Nothing) Then
                            Dim Position As Vector3
                            Dim modRotate As Single = 0
                            Dim modSideY As Single = 1
                            Dim modSideX As Single = 1
                            Dim i As Integer
                            For i = 0 To mTextMeshes.Length - 1
                                If lookAngleLH < CSng(Math.PI) / 2 Then
                                    If Not [text](i).ScaleX Then
                                        modSideY = 1
                                        modSideX = -1
                                        modRotate = 0
                                    Else
                                        modRotate = CSng(Math.PI)
                                        modSideY = 1
                                        modSideX = 1
                                    End If
                                Else
                                    If lookAngleLH < CSng(Math.PI) Then
                                        If Not [text](i).ScaleX Then
                                            modSideY = 1
                                            modSideX = -1
                                            modRotate = CSng(Math.PI)
                                        Else
                                            modRotate = CSng(Math.PI)
                                            modSideX = 1
                                            modSideY = -1
                                        End If
                                    Else
                                        If lookAngleLH < CSng(Math.PI) * 1.5 Then
                                            If Not [text](i).ScaleX Then
                                                modSideX = 1
                                                modSideY = 1
                                                modRotate = CSng(Math.PI)
                                            Else
                                                modRotate = 0 '(float)Math.PI;
                                                modSideY = -1
                                                modSideX = 1
                                            End If
                                        Else
                                            If Not [text](i).ScaleX Then
                                                modSideX = 1
                                                modSideY = 1
                                                modRotate = 0
                                            Else
                                                modSideX = 1
                                                modSideY = 1
                                                modRotate = 0
                                            End If
                                        End If
                                    End If
                                End If
                                Position = New Vector3([text](i).Position.X * modSideX, [text](i).Position.Y * modSideY, 0)

                                dx.Transform.World = Matrix.Translation((-1 * mTextCenters(i))) * Matrix.Scaling(-0.05F, 0.05F, 0.05F) * Matrix.RotationZ(([text](i).Rotation + modRotate)) * Matrix.Translation(Position)
                                dx.Material = GraphicsUtility.InitMaterial(Color.Blue)
                                dx.RenderState.Ambient = Color.Blue
                                mTextMeshes(i).M.DrawSubset(0)
                            Next i
                        End If
                    End If
                End If
            End If
            'dx.RenderState.Lighting = true;
            dx.RenderState.AlphaBlendEnable = False
        End If ' dx.SetTexture(0, null);
    End Sub 'Graph3D_DxRender3d

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        DeleteDirectxDevice()
        MyBase.Dispose(disposing)
    End Sub
End Class 'Graph3D

'
'ToDo: Error processing original source shown below
'
'
'-^--- expression expected
